#=========================================
#     FileName: master.py
#         Desc:
#       Author: ez~
#        Email: 2511384642@qq.com
#     HomePage: 
#      Version: 0.0.1
#   LastChange: 2021-08-04 16:02:14
#      Descrip:
#
#      主站模拟器
#=========================================

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial, threading, time

import utils



logger = modbus_tk.utils.create_logger("console")

def run(port):
    """主站模拟程序

    使用Configure Virtual Serial Port Driver创建如下虚拟串口对：
    COM1 --------> COM2
    COM3 --------> COM4
    COM5 --------> COM6
    因当前设备模拟环境不支持一主多从式模拟，因此先使用多主多从多线程模拟

    :param port: 当前模拟主站对应的串口号
    :type port: Serial

    """
    
    try:
        # 连接上位机通信标准
        # - 采用标准穿行RS485通讯口
        # - 数据传输速率：9600b/s
        # - 数据传输方式：异步
        # - 起始位：1bit
        # - 数据为：8bit
        # - 停止位：1bit
        # - 无校验位   

        master = modbus_rtu.RtuMaster(
            serial.Serial(port=port, baudrate=9600, bytesize=8, parity='N', stopbits=1, xonxoff=0)
        )
        master.set_timeout(5.0)
        master.set_verbose(True)

        while True:
            
            # 发送指令，参数说明：slave_id，funcode，block_addr(HL)，length(HL)：即字节乘个数（ex：01 04 0000 0002 71CB）
            # 模拟读取温湿度数据：01 04 0000 0002 CRCL CRCH
            recv = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 2)

            # 向物管平台推送数据
            data = {
                "temu": recv[0],
                "humi": recv[1]
            }
            statas = utils.push(data)
            assert statas == 200
            logger.info("数据上传成功")

            time.sleep(6)

    except modbus_tk.modbus.ModbusError as exc:
        logger.error("%s- FunctionCode=%d- Code=%d", exc, cst.READ_INPUT_REGISTERS, exc.get_exception_code())


if __name__ == "__main__":
    PORTS = [
        'COM1',
        'COM3',
        'COM5'
    ]
    threads = []
    for port in PORTS:
        threads.append(
            threading.Thread(target=run, args=(port, ))
        )
    for thread in threads:    
        thread.start()
    # for thread in threads:
    #     thread.join()
